<?php

namespace App\Http\Controllers\Admin;

use App\CodeResponse;
use App\Models\Certificate;
use App\Models\ExamCategory;
use App\Models\ExamPaper;
use App\Models\ExamPaperQuestion;
use App\Models\ExamQuestionOption;
use App\Models\Question;
use App\Models\QuestionOption;
use App\Services\CertificationExaminationService;
use App\Services\ExamPaperService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class ExamPaperController extends AdminController
{
    //保存
    public function save(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'integer|digits_between:1,20|min:1',
            'name' => 'required|string',
            'exam_category_id' => 'required|integer|digits_between:1,20|min:1',
            'certificate_id' => 'required|integer|digits_between:1,20|min:1',
            'is_published' => 'integer',
            'set_time_limit' => 'integer',
            'time_limit' => 'numeric',
            'certification_score' => 'required|numeric',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $putData = $request->except(['_method', '_token']);
        $users_id = Auth::id();
        if(isset($users_id)){
            $putData['users_id'] =  Auth::id()  ; //用户id
        }

        $id = $request->input('id');
        $flight = ExamPaper::updateOrCreate(
            ['id' => $id],
            $putData
        );
        return $this->success($flight->id);
    }
    //发布试卷
   public function  publishPage(Request $request)
   {
       $validator = Validator::make($request->all(), [
           'exam_paper_id' => 'required|integer|digits_between:1,20|min:1',
           'certificate_id' => 'required|integer|digits_between:1,20|min:1',
       ]);
       if ($validator->fails()) {
           return $this->fail(CodeResponse::PARAM_ILLEGAL);
       }
       $exam_paper_id= $request->input('exam_paper_id');
       $certificate_id = $request->input('certificate_id');
       //一个证书发布一个试卷后 该证书的其他试卷将下架
       $examPaperArr = ExamPaper::where('certificate_id',$certificate_id)->where('is_published',1)->get();
       foreach ($examPaperArr as $k=>$v) {
           $examPaper = ExamPaper::find($v->id);
           $examPaper->is_published = 2; //下架
           $examPaper->save();
       }
       $examPaper = ExamPaper::find($exam_paper_id);
       $examPaper->is_published = 1; //发布
       $examPaper->save();
       return $this->success($examPaper->is_published);
   }
    //列表
    public function  list(Request $request){
        $validator = Validator::make($request->all(), [
            'name' => 'string',
            'page' => 'integer',
            'limit' => 'integer',
            'sort' => 'string',
            'order' => 'string',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $name = $request->input('name');
        $exam_category_id = $request->input('exam_category_id');
        $certificate_id = $request->input('certificate_id');
        $is_published = $request->input('is_published');

        $page = $request->input('page',1);
        $limit = $request->input('limit',10);
        $sort = $request->input('sort','created_at');
        $order = $request->input('order','asc');

        $list = ExamPaperService::getInstance()->list($page,$limit,$sort,$order, $name,$exam_category_id,$certificate_id,$is_published);
        return $this->success($list);
    }
//删除
    public function delete(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $question = ExamPaper::find($request->id);
        $question->delete();
        return $this->success();
    }
    //获取信息
    public function getInfo(Request $request){
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $info =ExamPaperService::getInstance()->info($request->id);
        return $this->success($info);
    }
    //快速组卷
    public function generateQuickExam(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'exam_paper_id' => 'required|integer|digits_between:1,20|min:1',
            'question_category_id' => 'required',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        // 从请求中获取各种类型试题的数量
        $numberOfSingleChoice = $request->input('single_choice', 1);
        $numberOfMultipleChoice = $request->input('multiple_choice', 1);
        $numberOfFillInTheBlanks = $request->input('fill_in_the_blanks', 1);
        $numberOfShortAnswer = $request->input('short_answer', 1);
        $exam_paper_id = $request->input('exam_paper_id');
        $questionCategoryArr = $request->input('question_category_id');
        $questionCategoryIds = is_array($questionCategoryArr) ? $questionCategoryArr : json_decode($questionCategoryArr,true);

        //获取试卷已经存在的试题id
        $examPaperQuestionIds = $this->getExamPaperQuestionIds($exam_paper_id);
        // 初始化试卷数组
        $exam = [];
        // 检索单选题
        $singleChoiceQuestions = Question::where('question_type', 0)
            ->whereIn('question_category_id', $questionCategoryIds)
            ->whereNotIn('id', $examPaperQuestionIds)
            ->inRandomOrder()
            ->take($numberOfSingleChoice)
            ->get();

        // 检索多选题
        $multipleChoiceQuestions = Question::where('question_type', 1)
            ->whereIn('question_category_id', $questionCategoryIds)
            ->whereNotIn('id', $examPaperQuestionIds)
            ->inRandomOrder()
            ->take($numberOfMultipleChoice)
            ->get();
        // 判断题
        $estimateQuestions = Question::where('question_type', 2)
            ->whereIn('question_category_id', $questionCategoryIds)
            ->whereNotIn('id', $examPaperQuestionIds)
            ->inRandomOrder()
            ->take($numberOfMultipleChoice)
            ->get();
        // 检索填空题
        $fillInTheBlanksQuestions = Question::where('question_type', 3)
            ->whereIn('question_category_id', $questionCategoryIds)
            ->whereNotIn('id', $examPaperQuestionIds)
            ->inRandomOrder()
            ->take($numberOfFillInTheBlanks)
            ->get();
        // 检索简答题
        $shortAnswerQuestions = Question::where('question_type', 4)
            ->whereIn('question_category_id', $questionCategoryIds)
            ->whereNotIn('id', $examPaperQuestionIds)
            ->inRandomOrder()
            ->take($numberOfShortAnswer)
            ->get();
        // 将试题添加到试卷数组中
        $exam = array_merge($exam, $singleChoiceQuestions->toArray(), $multipleChoiceQuestions->toArray(),
            $estimateQuestions->toArray(),
            $fillInTheBlanksQuestions->toArray(),
            $shortAnswerQuestions->toArray(),
        );
        // 去除重复试题，确保试题不会重复
        $exam = array_unique($exam, SORT_REGULAR);
        // 提取试题的ID
        $questionIds = array_column($exam, 'id');
        // 查询选项
        $options = QuestionOption::whereIn('question_id', $questionIds)->get();

        $examWithOptions = [];
        // 遍历试题
        foreach ($exam as $k=>$v) {
            $exam[$k]['exam_paper_id'] = $exam_paper_id;
            $exam[$k]['options'] = [];
            $examWithOptions[$v['id']] = $exam[$k];
        }

        // 遍历选项，将选项与试题关联
        $options = $options->toArray();
        foreach ($options as $option) {
            if (isset($examWithOptions[$option['question_id']])) {
                $examWithOptions[$option['question_id']]['options'][] = $option;
            }
        }
        if (!empty($examWithOptions)){
            $res = ExamPaperService::getInstance()->addPage($examWithOptions);
        }else{
            $res = '该试卷中已存在此类别下的所有试题';
        }
        return $this->success($res);
    }
    // 获取试卷已经存在的试题id
    private function getExamPaperQuestionIds($examPaperId)
    {
        // 查找试卷
        $questionIds = ExamPaperQuestion::where('exam_paper_id',$examPaperId)->whereNotNull('question_id')
            ->pluck('question_id')->toArray();
        if (!$questionIds) {
            return [-1];
        }
        return $questionIds;
    }
    //添加试题
    public function addPaperQuestion(Request $request){
        $validator = Validator::make($request->all(), [
            'question_id' => 'required|integer|digits_between:1,20|min:1',
            'exam_paper_id' => 'required|integer|digits_between:1,20|min:1',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $question_id = $request->input('question_id');
        $exam_paper_id = $request->input('exam_paper_id');
        // 查询试题
        $questions = Question::where('id', $question_id)->get();
        // 查询选项
        $options = QuestionOption::where('question_id', $question_id)->get();
        $examWithOptions = [];
        // 遍历试题
        $questions = $questions->toArray();
        foreach ($questions as $k=>$v) {
            $questions[$k]['exam_paper_id'] = $exam_paper_id;
            $questions[$k]['options'] = [];
            $examWithOptions[$v['id']] = $questions[$k];
        }
        // 遍历选项，将选项与试题关联
        $options = $options->toArray();
        foreach ($options as $option) {
            if (isset($examWithOptions[$option['question_id']])) {
                $examWithOptions[$option['question_id']]['options'][] = $option;
            }
        }
        $res = ExamPaperService::getInstance()->addPage($examWithOptions);
        return $this->success($res);
    }
    //编辑试卷试题
    public function editPaperQuestion(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|digits_between:1,20|min:1',
            'name' => 'required|string',
            'question_stem' => 'required|string',
            'order' => 'required|numeric',
            'score' => 'required|numeric',
            'is_required' => 'integer',
            'is_displayed' => 'integer',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }

        $putData = $request->except(['_method', '_token', 'option_content']);
        $id = $request->input('id');
        $examPaperQuestion = ExamPaperQuestion::find($id);
        $examPaperQuestionId = -1;
        if($examPaperQuestion){
            $flight = ExamPaperQuestion::updateOrCreate(
                ['id' => $id],
                $putData
            );
            $optionContentArr = $request->input('option_content');
            $optionContentArr = is_array($optionContentArr) ? $optionContentArr : json_decode($optionContentArr,true);
            $examPaperQuestionId = $flight->id;
            $questionOption = ExamQuestionOption::where('exam_paper_question_id', $examPaperQuestionId);
            $questionOption->delete();
            if(is_array($optionContentArr)){
                foreach ($optionContentArr as $v ){
                    $v['exam_paper_question_id'] = $examPaperQuestionId;
                    $v['option_content'] = $v['option_content'] ;
                    $v['order'] = $v['order'] ;
                    $v['is_correct'] = $v['is_correct'] ;
                    ExamQuestionOption::create($v);
                }
            }
        }
        return $this->success($examPaperQuestionId);
    }
    //删除
    public function deletePaperQuestion(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $examPaperQuestion = ExamPaperQuestion::find($request->id);
        $examPaperQuestionId = -1;
        if($examPaperQuestion){
            $examPaperQuestionId = $examPaperQuestion->id;
            $examPaperQuestion->delete();
            $examQuestionOption = ExamQuestionOption::where('exam_paper_question_id',$request->id);
            $examQuestionOption->delete();
        }
        return $this->success($examPaperQuestionId);
    }
    //未被试卷引用试题列表
    public function  unreferencedQuestion(Request $request){
        $validator = Validator::make($request->all(), [
            'question_category_id' => 'required|integer',
            'question_type' => 'required|integer',
            'exam_paper_id' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $question_category_id = $request->input('question_category_id');
        $question_type = $request->input('question_type');
        $exam_paper_id = $request->input('exam_paper_id');
        //获取试卷已经存在的试题id
        $examPaperQuestionIds = $this->getExamPaperQuestionIds($exam_paper_id);

        $arr = ExamPaperService::getInstance()->unreferencedQuestion($question_category_id,$question_type,$examPaperQuestionIds);
        return $this->success($arr);
    }
    //试卷下的试题列表
    public function  listPaperQuestion(Request $request){
        $validator = Validator::make($request->all(), [
            'exam_paper_id' => 'required|integer',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $exam_paper_id = $request->input('exam_paper_id');
        $examPaper = ExamPaper::find($exam_paper_id);
        $examCategory = ExamCategory::where('id', $examPaper->exam_category_id)->first(); //试卷类别
        $certificate = Certificate::where('id', $examPaper->certificate_id	)->first();//证书

        $arr = ExamPaperService::getInstance()->listPaperQuestion($exam_paper_id);
        $order = array_column($arr, 'order');
        array_multisort($order, SORT_ASC, $arr); //排序
        $examPaperData = [
            'id' => $examPaper->id,
            'categoryName' => isset($examCategory) ? $examCategory->name : '',
            'certificateName' => isset($certificate) ? $certificate->name : '',
            'name' => $examPaper->name,
            'certification_score' => $examPaper->certification_score,
            'time_limit' => $examPaper->time_limit,
            'user_num' => $examPaper->user_num,
            'question_num' => $examPaper->question_num,
            'description' => $examPaper->description,
            'question' => $arr,
        ];

        return $this->success($examPaperData);
    }
    //修改分数
    public function updateQuestionScore(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|digits_between:1,20|min:1',
            'score' => 'required|numeric',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $putData = $request->except(['_method', '_token']);
        $id = $request->input('id');

        $examPaperQuestion = ExamPaperQuestion::find($id);
        $examPaperQuestionId = -1;
        if ($examPaperQuestion) {
            $flight = ExamPaperQuestion::updateOrCreate(
                ['id' => $id],
                $putData
            );
            $examPaperQuestionId = $flight->id;
        }
        return $this->success($examPaperQuestionId);
    }
    //编辑试题

    //上移
    public function moveUp(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|digits_between:1,20|min:1',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $id = $request->input('id');
        $question = ExamPaperQuestion::findOrFail($id); // 查找要操作的试题
        $currentOrder = $question->order;
        if ($currentOrder >= 0) { // 检查试题的当前顺序是否大于1
            $previousQuestion = ExamPaperQuestion::where('order', $currentOrder - 1)->first(); // 获取上一个试题
            if ($previousQuestion) {
                // 交换试题的顺序
                $previousOrder = $previousQuestion->order;
                $previousQuestion->order = $currentOrder;
                $question->order = $previousOrder;
                $previousQuestion->save();
                $question->save();
            }
        }

    }
    //下移
    public function moveDown(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id' => 'required|integer|digits_between:1,20|min:1',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $id = $request->input('id');
        $question = ExamPaperQuestion::findOrFail($id);
        $currentOrder = $question->order;
        $maxOrder = ExamPaperQuestion::max('order');
        if ($currentOrder < $maxOrder) { // 检查试题的当前顺序是否小于最大顺序
            $nextQuestion = ExamPaperQuestion::where('order', $currentOrder + 1)->first(); // 获取下一个试题
            if ($nextQuestion) {
                // 交换试题的顺序
                $nextOrder = $nextQuestion->order;
                $nextQuestion->order = $currentOrder;
                $question->order = $nextOrder;
                $nextQuestion->save();
                $question->save();
            }
        }
    }

    //用户试卷试卷列表
    public function  userPaperList(Request $request){
        $validator = Validator::make($request->all(), [
            'username' => 'string',
            'certificate_id' => 'integer',
            'page' => 'integer',
            'limit' => 'integer',
            'sort' => 'string',
            'order' => 'string',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $username = $request->input('username');
        $certificate_id = $request->input('certificate_id');
        $page = $request->input('page',1);
        $limit = $request->input('limit',10);
        $sort = $request->input('sort','created_at');
        $order = $request->input('order','asc');

        $list = ExamPaperService::getInstance()->userPaperList($username,$certificate_id,$page,$limit,$sort,$order);
        return $this->success($list);
    }
    //用户试卷试卷详情
    public function  userPaperInfo(Request $request){
        $validator = Validator::make($request->all(), [
            'exam_paper_id' => 'required|integer|digits_between:1,20|min:1',
            'certificate_id' => 'required|integer|digits_between:1,20|min:1',
            'users_id' => 'required|integer|digits_between:1,20|min:1',
        ]);
        if ($validator->fails()) {
            return $this->fail(CodeResponse::PARAM_ILLEGAL);
        }
        $exam_paper_id= $request->input('exam_paper_id');
        $certificate_id = $request->input('certificate_id');
        $users_id = $request->input('users_id');
//        $users_id = Auth::id();
//        if(!isset($users_id)){
//            return $this->success($arr = [101, '未登录不能进行答题']);
//        }
        $examPaper = ExamPaperService::getInstance()->userPaperInfo($users_id,$exam_paper_id,$certificate_id);
        $arr = [];
        if($examPaper){
            $arr = CertificationExaminationService::getInstance()->paperQuestion($users_id,$certificate_id,$exam_paper_id);
        }

        if(count($arr) < 1){
            return $this->fail( CodeResponse::CERTIFICATE_PAPER_INVALID);
        }else{
            return $this->success( [$examPaper,$arr]);
        }

    }
}
